Tổng quan về Tập dữ liệu Chất lượng Rượu¶

  • Tập dữ liệu này liên quan đến các loại rượu Vinho Verde của Bồ Đào Nha, bao gồm cả rượu vang đỏ và vang trắng (dù mô tả này chỉ đề cập chung, thường tập dữ liệu được tách làm hai file riêng biệt: red_wine và white_wine). Dữ liệu được thu thập và công bố bởi Cortez et al. (2009).

Nội dung Dữ liệu¶

Tập dữ liệu này chỉ chứa các biến lý hóa (physicochemical) và cảm quan (sensory). Do các vấn đề về bảo mật và hậu cần, không có dữ liệu về các yếu tố thương mại hay nông nghiệp như loại nho, thương hiệu rượu, hoặc giá bán.

Các Biến Đầu vào (Input Variables - Dựa trên kiểm tra lý hóa)¶

Đây là các đặc trưng được sử dụng để dự đoán chất lượng rượu:

  • fixed acidity: Độ axit cố định (không dễ bay hơi), chủ yếu là axit tartaric.

  • volatile acidity: Độ axit dễ bay hơi, chủ yếu là axit acetic (lượng cao thường cho thấy rượu bị hỏng).

  • citric acid: Axit citric, có thể làm tăng "độ tươi" và hương vị cho rượu.

  • residual sugar: Lượng đường còn lại sau khi quá trình lên men dừng lại.

  • chlorides: Lượng muối trong rượu.

  • free sulfur dioxide: Dạng SO₂ không liên kết, được thêm vào để ngăn chặn sự phát triển của vi khuẩn và quá trình oxy hóa.

  • total sulfur dioxide: Tổng lượng SO₂ ở dạng tự do và liên kết

  • density: Mật độ, có liên quan đến nồng độ cồn và lượng đường.

  • pH: Mức độ axit, có ảnh hưởng đến màu sắc và tiềm năng oxy hóa của rượu.

  • sulphates: Chất phụ gia rượu (thường ở dạng kali_sulphate) có thể góp phần vào mức SO₂ tổng thể.

  • Alcohol: Nồng độ cồn trong rượu.

Biến Đầu ra (Output Variable - Dựa trên dữ liệu cảm quan)

  • quality: Chất lượng rượu, được đánh giá dựa trên dữ liệu cảm quan (thường là điểm trung bình từ các nhà nếm rượu chuyên nghiệp), với thang điểm từ 0 đến 10.

Tính chất của Tập dữ liệu và Ứng dụng¶

  • Phân loại và Hồi quy

    • Tập dữ liệu này có thể được xử lý dưới dạng bài toán Phân loại (Classification) hoặc Hồi quy (Regression).
      • Hồi quy: Dự đoán điểm chất lượng thực tế (từ 0 đến 10).
      • Phân loại: Chuyển đổi điểm chất lượng thành các lớp nhị phân (ví dụ: "Tốt" / "Không tốt") hoặc đa lớp.
  • Đặc điểm Quan trọng

    • Lớp không cân bằng (Imbalanced Classes): Các lớp chất lượng được sắp xếp theo thứ tự, nhưng không cân bằng. Điều này có nghĩa là số lượng rượu chất lượng trung bình (ví dụ: điểm 5 hoặc 6) nhiều hơn đáng kể so với rượu chất lượng xuất sắc (ví dụ: điểm 8) hoặc kém (ví dụ: điểm 3).
  • Gợi ý Xử lý và Phân tích (Tips)

    • Chuyển đổi sang Phân loại Nhị phân: Một gợi ý phổ biến là đặt một ngưỡng tùy ý (arbitrary cutoff) cho biến đầu ra. Ví dụ, rượu có điểm quality≥7 được phân loại là 'good/1' và phần còn lại là 'not good/0'.
    • Mục tiêu Machine Learning: Mục tiêu chính là sử dụng các thuộc tính lý hóa để dự đoán hoặc xác định những yếu tố nào tạo nên một chai rượu "tốt".
    • Kỹ thuật và Công cụ: Dữ liệu này rất phù hợp để thực hành các kỹ thuật như Điều chỉnh siêu tham số (Hyper parameter tuning) trên các thuật toán như Cây Quyết định (Decision Tree), đánh giá bằng đường cong ROC (Receiver Operating Characteristic) và giá trị AUC (Area Under the Curve).
In [15]:
import pandas as pd  #for data manipulation operations
import numpy as np  #for numeric operations on data
import seaborn as sns  #for data visualization operations
import matplotlib.pyplot as plt  #for data visualization operations
from sklearn.preprocessing import LabelEncoder # for encoding
from sklearn.preprocessing import MinMaxScaler, RobustScaler, StandardScaler #for standardization
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
import scipy.stats as st

#from markupsafe import escape
#!pip install pandas-profiling
#import pandas_profiling

from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn import model_selection
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import GradientBoostingClassifier
#!pip install lightgbm
# from lightgbm import LGBMClassifier

#ignore warnings
import warnings
warnings.filterwarnings("ignore")

#see model parametres
from sklearn import set_config
set_config(print_changed_only = False)
In [16]:
# Đọc file winequality-red.csv
wine_data = pd.read_csv("winequality-red.csv")

# wine_data.head(5)

wine_df = wine_data.copy()
wine_df.head(n = 10).style.background_gradient(cmap = "Purples_r")
Out[16]:
  fixed acidity volatile acidity citric acid residual sugar chlorides free sulfur dioxide total sulfur dioxide density pH sulphates alcohol quality
0 7.400000 0.700000 0.000000 1.900000 0.076000 11.000000 34.000000 0.997800 3.510000 0.560000 9.400000 5
1 7.800000 0.880000 0.000000 2.600000 0.098000 25.000000 67.000000 0.996800 3.200000 0.680000 9.800000 5
2 7.800000 0.760000 0.040000 2.300000 0.092000 15.000000 54.000000 0.997000 3.260000 0.650000 9.800000 5
3 11.200000 0.280000 0.560000 1.900000 0.075000 17.000000 60.000000 0.998000 3.160000 0.580000 9.800000 6
4 7.400000 0.700000 0.000000 1.900000 0.076000 11.000000 34.000000 0.997800 3.510000 0.560000 9.400000 5
5 7.400000 0.660000 0.000000 1.800000 0.075000 13.000000 40.000000 0.997800 3.510000 0.560000 9.400000 5
6 7.900000 0.600000 0.060000 1.600000 0.069000 15.000000 59.000000 0.996400 3.300000 0.460000 9.400000 5
7 7.300000 0.650000 0.000000 1.200000 0.065000 15.000000 21.000000 0.994600 3.390000 0.470000 10.000000 7
8 7.800000 0.580000 0.020000 2.000000 0.073000 9.000000 18.000000 0.996800 3.360000 0.570000 9.500000 7
9 7.500000 0.500000 0.360000 6.100000 0.071000 17.000000 102.000000 0.997800 3.350000 0.800000 10.500000 5

Trong đoạn mã trên, chúng ta tải tập dữ liệu. Sau đó, để phòng trường hợp cần thiết, chúng ta tạo một bản sao của tập dữ liệu, vì đôi khi có thể cần dùng đến tập dữ liệu gốc.

In [17]:
wine_df.shape
Out[17]:
(1599, 12)
  • Tập dữ liệu gồm 1599 hàng và 12 cột.
In [18]:
#Show the top rows of the dataframe
wine_data.head()
Out[18]:
fixed acidity volatile acidity citric acid residual sugar chlorides free sulfur dioxide total sulfur dioxide density pH sulphates alcohol quality
0 7.4 0.70 0.00 1.9 0.076 11.0 34.0 0.9978 3.51 0.56 9.4 5
1 7.8 0.88 0.00 2.6 0.098 25.0 67.0 0.9968 3.20 0.68 9.8 5
2 7.8 0.76 0.04 2.3 0.092 15.0 54.0 0.9970 3.26 0.65 9.8 5
3 11.2 0.28 0.56 1.9 0.075 17.0 60.0 0.9980 3.16 0.58 9.8 6
4 7.4 0.70 0.00 1.9 0.076 11.0 34.0 0.9978 3.51 0.56 9.4 5
  • Hiển thị 5 dòng đầu tiên của tập dữ liệu
In [19]:
# Display the last five rows of the dataframe.
wine_data.tail()
Out[19]:
fixed acidity volatile acidity citric acid residual sugar chlorides free sulfur dioxide total sulfur dioxide density pH sulphates alcohol quality
1594 6.2 0.600 0.08 2.0 0.090 32.0 44.0 0.99490 3.45 0.58 10.5 5
1595 5.9 0.550 0.10 2.2 0.062 39.0 51.0 0.99512 3.52 0.76 11.2 6
1596 6.3 0.510 0.13 2.3 0.076 29.0 40.0 0.99574 3.42 0.75 11.0 6
1597 5.9 0.645 0.12 2.0 0.075 32.0 44.0 0.99547 3.57 0.71 10.2 5
1598 6.0 0.310 0.47 3.6 0.067 18.0 42.0 0.99549 3.39 0.66 11.0 6
  • Hiển thị 5 dòng dữ liệu cuối của tập dữ liệu
In [20]:
wine_data.columns
Out[20]:
Index(['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar',
       'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density',
       'pH', 'sulphates', 'alcohol', 'quality'],
      dtype='object')
  • Số lượng cột trong tập dữ liệu
In [21]:
wine_df.columns = [s.strip().replace(' ', '_') for s in wine_data.columns]
wine_df.columns
Out[21]:
Index(['fixed_acidity', 'volatile_acidity', 'citric_acid', 'residual_sugar',
       'chlorides', 'free_sulfur_dioxide', 'total_sulfur_dioxide', 'density',
       'pH', 'sulphates', 'alcohol', 'quality'],
      dtype='object')
  • Đổi tên cột (nhưng tên cột có khoảng trắng sẽ thay bằng _ )
In [22]:
wine_df.describe().T.style.background_gradient(cmap = "magma")
Out[22]:
  count mean std min 25% 50% 75% max
fixed_acidity 1599.000000 8.319637 1.741096 4.600000 7.100000 7.900000 9.200000 15.900000
volatile_acidity 1599.000000 0.527821 0.179060 0.120000 0.390000 0.520000 0.640000 1.580000
citric_acid 1599.000000 0.270976 0.194801 0.000000 0.090000 0.260000 0.420000 1.000000
residual_sugar 1599.000000 2.538806 1.409928 0.900000 1.900000 2.200000 2.600000 15.500000
chlorides 1599.000000 0.087467 0.047065 0.012000 0.070000 0.079000 0.090000 0.611000
free_sulfur_dioxide 1599.000000 15.874922 10.460157 1.000000 7.000000 14.000000 21.000000 72.000000
total_sulfur_dioxide 1599.000000 46.467792 32.895324 6.000000 22.000000 38.000000 62.000000 289.000000
density 1599.000000 0.996747 0.001887 0.990070 0.995600 0.996750 0.997835 1.003690
pH 1599.000000 3.311113 0.154386 2.740000 3.210000 3.310000 3.400000 4.010000
sulphates 1599.000000 0.658149 0.169507 0.330000 0.550000 0.620000 0.730000 2.000000
alcohol 1599.000000 10.422983 1.065668 8.400000 9.500000 10.200000 11.100000 14.900000
quality 1599.000000 5.636023 0.807569 3.000000 5.000000 6.000000 6.000000 8.000000
  • Thông qua bảng phân bố như thế này ta có Nhận xét:
    • Giá trị trung bình của fixed acidity là 8.32, giá trị cao nhất là 15.9
    • Giá trị trung bình của volatile acidity là 0.53, giá trị cao nhất là 1.58
    • Giá trị trung bình của citric acid là 0.27, giá trị cao nhất là 1
    • Giá trị trung bình của residual sugar là 2.54, giá trị cao nhất là 15.5
    • Giá trị trung bình của chlorides là 0.09, giá trị cao nhất là 0.61
    • Giá trị trung bình của free sulfur dioxide là 15.88, giá trị cao nhất là 72
    • Giá trị trung bình của total sulfur dioxide là 46.47, giá trị cao nhất là 289
    • Giá trị trung bình của density là 0.997, giá trị cao nhất là 1
    • Giá trị trung bình của pH là 3.31, giá trị cao nhất là 4.01
    • Giá trị trung bình của sulphates là 0.66, giá trị cao nhất là 2
    • Giá trị trung bình của alcohol là 10.42, giá trị cao nhất là 14.90
    • Giá trị trung bình của quality là 5.64, giá trị cao nhất là 8
In [23]:
wine_df.dtypes
Out[23]:
fixed_acidity           float64
volatile_acidity        float64
citric_acid             float64
residual_sugar          float64
chlorides               float64
free_sulfur_dioxide     float64
total_sulfur_dioxide    float64
density                 float64
pH                      float64
sulphates               float64
alcohol                 float64
quality                   int64
dtype: object
  • Kiểu dữ liệu của tất cả các biến đều là số.
In [24]:
print(wine_df.isnull().sum())
fixed_acidity           0
volatile_acidity        0
citric_acid             0
residual_sugar          0
chlorides               0
free_sulfur_dioxide     0
total_sulfur_dioxide    0
density                 0
pH                      0
sulphates               0
alcohol                 0
quality                 0
dtype: int64
  • Không có bất kỳ giá trị null nào trong tập dữ liệu. Tổng số giá trị "null" trong tập dữ liệu là 0.
In [25]:
fig, axes = plt.subplots(1, 3, figsize = (40, 10))

sns.histplot(ax = axes[0], x = wine_df["fixed_acidity"],
             bins = 10,
             kde = True,
             color = "#CA96EC").set(title = "Distribution of 'fixed_acidity'")

sns.histplot(ax = axes[1], x = wine_df["volatile_acidity"],
             bins = 10,
             kde = True,
             color = "#A163CF").set(title = "Distribution of 'volatile_acidity'")

sns.histplot(ax = axes[2], x = wine_df["citric_acid"],
             bins = 10,
             kde = True,   
             color = "#29066B").set(title = "Distribution of 'citric_acid'")

plt.show()
No description has been provided for this image
  • Nhận xét:
    • _Fixed acidity_: Phân bố khá giống chuẩn, tập trung nhiều quanh giá trị 7–8. Tuy nhiên hơi lệch phải nhẹ (skewed right), nghĩa là có một số rượu có độ axit cố định cao hơn mức phổ biến.
    • _Volatile acidity_: Phân bố không chuẩn, có dạng đa đỉnh (nhiều đỉnh). Phần lớn tập trung ở mức 0.4–0.6, nhưng vẫn có đỉnh phụ ở khoảng thấp hơn. Điều này cho thấy rượu có sự đa dạng rõ rệt về độ axit bay hơi.
    • _Citric acid_: Phân bố khá đặc biệt, với nhiều đỉnh rõ ràng. Giá trị bằng 0 xuất hiện nhiều (nghĩa là khá nhiều rượu không chứa axit citric). Các giá trị còn lại phân bố rải rác từ 0.1 đến 0.6, cho thấy mức độ axit citric trong rượu thay đổi mạnh.
In [26]:
fig, axes = plt.subplots(1, 3, figsize=(40, 10))

sns.histplot(ax = axes[0], x = wine_df["alcohol"],
             bins = 10,    
             kde = True,
             cbar = True,
             color = "#641811").set(title = "Distribution of 'alcohol'");

sns.histplot(ax = axes[1], x = wine_df["residual_sugar"],
             bins = 10,
             kde = True,
             cbar = True,
             color = "#EB548C").set(title = "Distribution of 'residual_sugar'");

sns.histplot(ax = axes[2], x = wine_df["chlorides"],
             bins = 10,
             kde = True,   
             cbar = True,
             color = "#EC96E0").set(title = "Distribution of 'chlorides'");

plt.show()
No description has been provided for this image
  • Nhận xét:
    • _Alcohol_: Phân bố lệch phải rõ rệt (right-skewed). Phần lớn mẫu tập trung ở mức 9–11 độ cồn. Một số ít rượu có độ cồn cao hơn (tới gần 15), nhưng khá hiếm.

      • -> Điều này cho thấy đa số rượu có nồng độ cồn trung bình, rượu có độ cồn cao là ngoại lệ.
    • _Residual sugar_: Phân bố lệch phải mạnh. Phần lớn mẫu tập trung quanh mức 2–3 g/L, số lượng giảm nhanh khi đường dư cao hơn. Có vài ngoại lệ (outliers) với giá trị đường dư lên tới 10–15 g/L, nhưng cực kỳ ít.

      • -> Điều này phản ánh đa số rượu không ngọt nhiều, chỉ một số nhỏ có lượng đường cao.
    • _Chlorides_: Phân bố cũng lệch phải rất mạnh. Hầu hết giá trị tập trung quanh mức 0.07–0.1. Một số ít ngoại lệ có giá trị cao tới 0.5–0.6.

      • -> Nhìn chung, đa phần rượu có lượng muối thấp, chỉ vài mẫu vượt trội hẳn.
In [27]:
sns.pairplot(wine_df, diag_kind = "hist", hue = "quality", height = 3, aspect = 1.2, corner = True);
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Phân phối các biến (ô chéo chính):

      • Nhiều biến không tuân theo phân phối chuẩn (ví dụ residual_sugar, chlorides, sulphates bị lệch phải).
      • Một số biến có phân phối gần chuẩn hơn như fixed_acidity, citric_acid, alcohol.
    • Quan hệ giữa các biến (ô ngoài chéo):

      • Alcohol và quality: có xu hướng dương – rượu có nồng độ cồn cao thì chất lượng thường tốt hơn.
      • Volatile acidity và quality: có xu hướng âm – độ chua bay hơi cao thì chất lượng giảm.
      • Citric acid và quality: hơi dương – nhiều acid citric có thể liên quan đến chất lượng cao hơn.
    • Một số biến có mối quan hệ khá rõ rệt với nhau:

      • density tỉ lệ thuận với residual_sugar và fixed_acidity.
      • pH có quan hệ nghịch với fixed_acidity.
    • Các cặp biến gần như không có quan hệ:

      • Ví dụ alcohol và chlorides, pH và alcohol — các điểm phân tán rất rời rạc, không theo quy luật rõ ràng.
In [28]:
# Include information about values
corr = wine_data.corr()
fig, ax = plt.subplots()
fig.set_size_inches(14, 8)
sns.heatmap(corr, annot=True, fmt=".1f", cmap="RdBu", center=0, ax=ax)

plt.show()
No description has been provided for this image
  • Nhận xét từ heatmap tương quan:
    • Quan hệ mạnh giữa các biến:

      • fixed_acidity ↔ density (0.7): độ acid cố định càng cao thì mật độ rượu càng lớn.
      • fixed_acidity ↔ citric_acid (0.7): rượu có nhiều acid cố định thì thường cũng có nhiều acid citric.
      • free_sulfur_dioxide ↔ total_sulfur_dioxide (0.7): hợp lý vì tổng SO₂ bao gồm SO₂ tự do.
    • Quan hệ nghịch mạnh:

      • fixed_acidity ↔ pH (-0.7): acid càng cao thì pH càng thấp (hợp lý về mặt hóa học).
      • density ↔ alcohol (-0.5): rượu có nồng độ cồn cao thì mật độ thấp hơn.
    • Các biến liên quan đến chất lượng (quality):

      • alcohol có tương quan dương tương đối mạnh (0.5) → rượu có nhiều cồn thì thường được đánh giá chất lượng cao hơn.
      • volatile_acidity có tương quan âm (-0.4) → acid bay hơi nhiều làm giảm chất lượng rượu.
      • citric_acid có tương quan dương nhẹ (0.2) → acid citric góp phần tăng chất lượng.
      • Các biến khác (residual_sugar, chlorides, SO₂, density) hầu như không ảnh hưởng đáng kể.
    • Ý nghĩa tổng quát:

      • Không phải tất cả biến đều ảnh hưởng đến chất lượng rượu.
      • Ba biến quan trọng nhất để dự đoán chất lượng: alcohol, volatile_acidity, citric_acid.
In [29]:
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
axes = axes.flatten()

sns.scatterplot(ax = axes[0],
                x = "residual_sugar",
                y = "quality", hue = "quality",
                data = wine_df).set(title = "Relationship between 'residual_sugar' and 'quality'");

sns.scatterplot(ax = axes[1],
                x = "alcohol",
                y = "quality", hue = "quality",
                data = wine_df).set(title = "Relationship between 'alcohol' and 'quality'");

sns.scatterplot(ax = axes[2],
                x = "pH",
                y = "quality", hue = "quality",
                data = wine_df).set(title = "Relationship between 'pH' and 'quality'");

sns.scatterplot(ax = axes[3],
                x = "density",
                y = "quality", hue = "quality",
                data = wine_df).set(title = "Relationship between 'density' and 'quality'");

plt.show()
No description has been provided for this image
  • Nhận xét:

      1. Residual Sugar vs Quality
      • Phần lớn rượu có lượng residual sugar thấp (≤ 5).
      • Không có sự khác biệt rõ rệt về residual sugar giữa các mức chất lượng (3–8).

    -> Residual sugar không ảnh hưởng mạnh đến quality.

      1. Alcohol vs Quality
      • Có xu hướng: rượu có alcohol cao hơn (≥ 11) thường đạt quality cao hơn (6–8).
      • Rượu có alcohol thấp (≈ 9–10) tập trung nhiều ở chất lượng thấp (3–5).

    -> Alcohol có mối quan hệ tích cực với quality.

      1. pH vs Quality
      • Phần lớn rượu có pH tập trung quanh 3.1 – 3.4.
      • Không có sự khác biệt rõ ràng giữa các nhóm quality theo pH.

    -> pH không phải yếu tố chính ảnh hưởng đến quality.

      1. Density vs Quality
      • Density tập trung mạnh trong khoảng 0.995 – 1.000.
      • Có xu hướng rượu chất lượng cao (7–8) thường nằm ở mức density thấp hơn một chút.

    -> Density có thể liên quan ngược chiều với quality (density thấp → chất lượng tốt hơn).

In [30]:
sns.scatterplot(x = "residual_sugar",
                y = "pH",
                hue = "quality",
                data = wine_df).set(title = "Relationship between 'residual_sugar' and 'pH'");
No description has been provided for this image
  • Nhận xét:
    • Phân bố dữ liệu:

      • Phần lớn điểm dữ liệu tập trung ở residual_sugar từ 1–5 và pH khoảng 3.0–3.5.
      • Một số ít rượu có lượng đường dư cao (>10), nhưng đó là ngoại lệ, chiếm tỷ lệ rất nhỏ.
    • Mối quan hệ giữa residual_sugar và pH

      • Không thấy mối quan hệ tuyến tính rõ ràng (tức là residual_sugar tăng không đồng nghĩa pH tăng hay giảm theo quy luật).
      • Dữ liệu khá phân tán, nhưng đa phần tập trung thành “cụm dày” ở vùng residual_sugar thấp và pH trung bình (3.0–3.4).
    • Theo chất lượng (quality)

      • Các điểm thuộc mọi mức chất lượng (3–8) đều xuất hiện trong vùng tập trung chính → tức là chỉ dựa vào residual_sugar và pH thì khó phân biệt rõ rệt các nhóm chất lượng rượu.
      • Tuy nhiên, rượu chất lượng cao (7–8, màu đậm hơn) dường như cũng tập trung nhiều ở vùng residual_sugar thấp (khoảng 2–3) và pH từ 3.1–3.4.
In [31]:
sns.scatterplot(x = "alcohol",
                y = "pH",
                hue = "quality",
                palette = "magma",
                data = wine_df).set(title = "Relationship between 'alcohol' and 'pH'");
No description has been provided for this image
  • Nhận xét:
    • Phân bố dữ liệu:

      • Dữ liệu tập trung chủ yếu trong khoảng alcohol từ 9–12 và pH từ 3.0–3.4.
      • Một số ít rượu có nồng độ cồn cao (>13) nhưng không nhiều, chủ yếu thuộc nhóm chất lượng khá/tốt.
    • Mối quan hệ giữa alcohol và pH

      • Có xu hướng cùng tăng nhẹ: khi alcohol tăng, pH có xu hướng cao hơn một chút, nhưng quan hệ này không mạnh.
      • Các điểm vẫn phân tán, không tạo thành đường rõ ràng.
    • Theo chất lượng (quality)

      • Rượu chất lượng thấp (3–4) xuất hiện nhiều ở vùng alcohol thấp (8–10).
      • Rượu chất lượng cao (7–8) xuất hiện nhiều hơn ở vùng alcohol cao (≥11), pH thường quanh 3.2–3.4.
      • Điều này gợi ý rằng nồng độ cồn cao có liên quan đến chất lượng rượu tốt hơn, trong khi pH không phải yếu tố quyết định mạnh.
In [32]:
fig, axes = plt.subplots(nrows = 4, ncols = 3, figsize = (20, 20))

colors = ['#491D8B', '#6929C4', '#8A3FFC', '#A56EFF',
          '#7D3AC1', '#AF4BCE', '#DB4CB2', '#EB548C',
          '#EC96E0', '#A2128E', '#E8D9F3', '#641811']

for index, column in enumerate(wine_df.columns):
    ax = axes.flatten()[index]
    ax.hist(wine_df[column], color = colors[index], label = column)
    ax.legend(loc = "best")
plt.suptitle("Histograms", size = 18)

plt.show()
No description has been provided for this image
  • Nhận xét:
    • Fixed Acidity:

      • Phân bố lệch phải nhẹ (right-skewed).
      • Chủ yếu dao động từ 6–10, tập trung khoảng 7–8.
    • Volatile Acidity:

      • Phân bố hơi lệch phải, phần lớn giá trị từ 0.3–0.7.
      • Có vài trường hợp ngoại lai (outliers) trên 1.
    • Citric Acid:

      • Phân bố khá phân tán, không đều, nhiều “đỉnh nhỏ” (multi-modal).
      • Nhiều mẫu có citric acid = 0 (không chứa).
    • Residual Sugar:

      • Rất lệch phải, phần lớn giá trị < 3.
      • Một số ít trường hợp có giá trị rất cao (~10–15), có thể là ngoại lai.
    • Chlorides:

      • Lệch phải rõ rệt, hầu hết < 0.15.
      • Một vài ngoại lai với giá trị > 0.4.
    • Free Sulfur Dioxide:

      • Phân bố lệch phải, tập trung khoảng 5–35.
      • Có mẫu cực cao (~70).
    • Total Sulfur Dioxide:

      • Lệch phải mạnh, đa số nằm trong khoảng 20–150.
      • Một số giá trị ngoại lai > 200.
    • Density:

      • Phân bố gần chuẩn (normal-like), tập trung mạnh trong khoảng 0.994–0.998.
    • pH:

      • Phân bố gần chuẩn, tập trung quanh 3.2–3.4.
    • Sulphates:

      • Lệch phải nhẹ, tập trung quanh 0.5–0.7.
      • Có vài điểm cao > 1.5 (outliers).
    • Alcohol:

      • Lệch phải, đa số nằm trong khoảng 9–11.
      • Một số rượu có độ cồn cao (12–14).
    • Quality:

      • Phân bố rời rạc (categorical-like).
      • Phần lớn rượu có chất lượng 5–6 (chiếm nhiều nhất).
      • Ít rượu chất lượng thấp (3–4) hoặc cao (7–8).
In [34]:
dataForPlot = wine_df.groupby('quality').mean().total_sulfur_dioxide
fig, ax = plt.subplots()
ax.bar(dataForPlot.index, dataForPlot, color=['C0','C1','C3','C4','C5','C6'])
ax.set_xticks([3, 4, 5, 6, 7, 8])
ax.set_xlabel('Quality')
ax.set_ylabel('Avg. Total Sulfur Dioxide')
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Rượu có chất lượng 5 có tổng lượng sulfur dioxide trung bình cao nhất (~57).
    • → Cho thấy sulfur dioxide có xu hướng nhiều nhất ở mức chất lượng trung bình.

    • Chất lượng thấp (3, 4) có sulfur dioxide thấp hơn so với mức 5, nhưng vẫn tăng dần từ 3 → 4 → 5.
    • Chất lượng cao (6, 7, 8) lại có mức sulfur dioxide trung bình thấp hơn, giảm dần so với 5.
    • Từ mức 6 trở đi, sulfur dioxide giảm xuống khoảng 35–40.
    • Xu hướng tổng thể:
      • Sulfur dioxide cao nhất ở rượu chất lượng trung bình (5).
      • Rượu chất lượng cao (7–8) có xu hướng ít sulfur dioxide hơn → có thể liên quan đến chất lượng cảm quan (sulfur dioxide cao thường ảnh hưởng vị và mùi).
In [35]:
dataForPlot = wine_df.groupby('quality').mean().residual_sugar
fig, ax = plt.subplots()
ax.bar(dataForPlot.index, dataForPlot, color=['C0'])
ax.set_xticks([3, 4, 5, 6, 7, 8])
ax.set_xlabel('Quality')
ax.set_ylabel('Avg. Residual Sugar')
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Giá trị trung bình của Residual Sugar dao động trong khoảng ~2.5–2.7, tức là không có sự chênh lệch quá lớn giữa các mức chất lượng.
    • Rượu chất lượng 4 và 7 có lượng đường dư trung bình cao nhất (~2.7).
    • Đặc biệt, mức 7 (chất lượng cao) vẫn giữ đường dư tương đối nhiều.
    • Rượu chất lượng 6 có lượng đường dư trung bình thấp nhất (~2.48).
    • Không thấy xu hướng tuyến tính rõ ràng (ví dụ: không phải đường dư càng thấp thì rượu càng ngon).
In [36]:
wine_df.plot.scatter(x='fixed_acidity', y='pH', legend=False)
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Mối quan hệ nghịch rõ rệt:

      • Khi fixed acidity tăng, thì pH giảm.
      • Điều này hợp lý về mặt hóa học: độ axit cao hơn thì pH thấp hơn.
    • Phân bố dữ liệu tập trung nhiều nhất:

      • fixed_acidity nằm trong khoảng 6–10.
      • pH nằm trong khoảng 3.0–3.5.
    • Một số giá trị ngoại lai (outliers):

      • Ở mức fixed_acidity > 13 hoặc < 5 có ít điểm dữ liệu.
      • Tương tự, có một số rượu có pH gần 4.0 hoặc dưới 2.9, hiếm gặp.
    • Quan hệ gần tuyến tính nghịch:

      • Đường xu hướng có thể được mô tả bằng hồi quy tuyến tính âm.
  • Biểu đồ này là một bước kiểm tra dữ liệu quan trọng, xác nhận rằng các biến số liên quan đến độ axit trong tập dữ liệu đang hoạt động theo đúng nguyên tắc hóa học. Nó cho thấy mối tương quan nghịch mạnh mẽ giữa Độ Chua Cố Định và pH.
In [37]:
dataForPlot = wine_df.groupby('quality').mean().free_sulfur_dioxide
fig, ax = plt.subplots()
ax.bar(dataForPlot.index, dataForPlot, color=['C0'])
ax.set_xticks([3, 4, 5, 6, 7, 8])
ax.set_xlabel('Quality')
ax.set_ylabel('Avg. of free_sulfur_dioxide')
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Xu hướng chung:

      • Hàm lượng free sulfur dioxide tăng dần khi chất lượng rượu từ 3 → 5.
      • Đạt mức cao nhất ở chất lượng 5 (~17).
    • Sau đó có xu hướng giảm:

      • Từ chất lượng 6 → 8, giá trị trung bình free sulfur dioxide giảm dần (~15 → 13).
    • Ý nghĩa:

      • Lượng free sulfur dioxide (SO₂ tự do) vừa phải có thể góp phần bảo quản rượu và giữ hương vị, nhưng quá nhiều hay quá ít đều không đảm bảo chất lượng tối ưu.
      • Chất lượng trung bình (5–6) lại có mức SO₂ cao nhất, trong khi rượu chất lượng cao hơn (7–8) có xu hướng ít SO₂ hơn, có thể do quá trình sản xuất tinh chỉnh hơn, ít phụ thuộc vào chất bảo quản.
  • biểu đồ này cho thấy SO2 Tự do đạt đỉnh ở chất lượng Q=5 và có mối quan hệ nghịch với chất lượng cao hơn (Q=6,7,8). Điều này gợi ý rằng lượng SO2 Tự do quá cao thường là đặc điểm của rượu vang chất lượng trung bình/thấp.
In [38]:
plt.boxplot([wine_df['free_sulfur_dioxide'], wine_df['total_sulfur_dioxide']], vert=False)

plt.xlabel('Sulphur Dioxide')
plt.ylabel('Wine Quality')
plt.title('Free vs Total Sulphur Dioxide in Wine')
plt.yticks([1, 2], ['Free', 'Total'])

plt.show()
No description has been provided for this image
  • Nhận xét:
    • Tổng thể:

      • Total Sulphur Dioxide (SO₂ tổng) có giá trị lớn hơn rất nhiều so với Free Sulphur Dioxide (SO₂ tự do).
      • Điều này hợp lý vì SO₂ tổng bao gồm cả SO₂ tự do + SO₂ liên kết.
    • Phân bố:

      • Free Sulphur Dioxide:

        • Median (trung vị) khoảng ~15.
        • Phần lớn dữ liệu nằm trong khoảng 10 – 25.
        • Có một số outlier (giá trị ngoại lệ) trên 50.
      • Total Sulphur Dioxide:

        • Median cao hơn, khoảng ~35.
        • Phần lớn dữ liệu tập trung 20 – 60.
        • Có nhiều outlier rất lớn, thậm chí trên 200 – 300, cho thấy một số mẫu rượu có sử dụng lượng SO₂ tổng cực kỳ cao.
    • So sánh mức độ biến động:

      • Total SO₂ có biến thiên rộng hơn nhiều so với Free SO₂.
      • Free SO₂ tương đối ổn định, ít giá trị ngoại lệ hơn.
  • biểu đồ này trực quan hóa một cách hiệu quả sự khác biệt về quy mô và phân bố giữa hai dạng SO2, nhấn mạnh rằng SO2 Tổng cộng có giá trị trung vị, phạm vi và các giá trị cực đoan cao hơn nhiều.
In [43]:
# Calculate the sum of density and sum of residual sugar for each row
wine_df['sum_density_residual_sugar'] = wine_df['density'] + wine_df['residual_sugar']

# Create a scatter plot with quality as the color of each point
plt.scatter(wine_df['quality'],wine_df['sum_density_residual_sugar'],  c=wine_df['quality'])
plt.xlabel('Sum of Density and Residual Sugar')
plt.ylabel('Quality')
plt.colorbar()
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Trục X: Tổng mật độ và đường dư (density + residual_sugar).

    • Trục Y: Chất lượng rượu (quality).

    • Màu sắc: Phân biệt các mức chất lượng (từ 3 → 8).

    • Phân bố dữ liệu:

      • Giá trị tổng density + residual_sugar chủ yếu nằm trong khoảng 3 đến 8.
      • Ở mức chất lượng thấp (3, 4, 5), giá trị này trải khá đều, không có sự khác biệt rõ rệt so với chất lượng cao hơn.
    • Xu hướng chất lượng:

      • Không thấy có mối quan hệ tuyến tính rõ ràng giữa density + residual_sugar và quality.
      • Các mức chất lượng khác nhau bị chồng lấn mạnh (cùng một giá trị tổng có nhiều chất lượng khác nhau).
      • Ví dụ: tại giá trị ~5–6, ta có cả rượu chất lượng 3, 4, 5, 6, 7, 8.
    • Kết luận sơ bộ:

      • Biến density + residual_sugar không phải là một đặc trưng mạnh để phân biệt chất lượng rượu.
      • Tuy nhiên, nó vẫn có thể hữu ích nếu kết hợp với các biến khác (alcohol, pH, sulfur dioxide...) trong mô hình dự đoán.
      • Nếu dùng riêng biến này để phân loại chất lượng, kết quả sẽ khá yếu vì dữ liệu bị chồng lấn nhiều.
In [46]:
sns.histplot(data=wine_df, x=wine_df.fixed_acidity, hue="quality", kde=True, bins=20, multiple="stack", alpha=.3)
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Trục X: Độ axit cố định (fixed_acidity), với giá trị trải từ khoảng 5 đến 16.

    • Trục Y: Số lượng mẫu (Count) tương ứng với mỗi khoảng giá trị fixed_acidity.

    • Màu sắc: Phân biệt các mức chất lượng rượu (quality) từ 3 đến 8.

    • Phân bố dữ liệu:

      • Phân bố chung của fixed_acidity: Tổng số lượng mẫu (khi cộng tất cả các màu) tập trung chủ yếu trong khoảng 6.5 đến 9.0, đạt đỉnh tại khoảng 7.5.
      • Phân bố theo Chất lượng (quality):
      • Các mức chất lượng trung bình (như quality=5 và quality=6) chiếm số lượng mẫu áp đảo và có sự phân bố rộng nhất, đỉnh của chúng nằm trong khoảng fixed_acidity tập trung (khoảng 7.0 đến 8.0).
      • Các mức chất lượng thấp (quality=3,4) và cao (quality=7,8) có số lượng mẫu rất ít so với quality=5,6.
      • Chất lượng cao nhất (quality=8) có phân bố trải rộng nhưng số lượng mẫu rất ít, với đỉnh phân bố tập trung rõ rệt quanh 7.5 và một lượng nhỏ trải đến 10-11.
      • Chất lượng thấp nhất (quality=3) và (quality=4) cũng có phân bố tương tự, nhưng chủ yếu nằm trong khoảng 6.0 đến 9.0.
    • Xu hướng chất lượng:

      • Chồng lấn mạnh mẽ: Biểu đồ cho thấy sự chồng lấn rất lớn giữa các mức chất lượng (quality) trên toàn bộ phạm vi giá trị fixed_acidity. Cụ thể, trong khoảng giá trị fixed_acidity phổ biến nhất (khoảng 6.5 đến 9.0), ta tìm thấy mẫu của tất cả các mức chất lượng từ 3 đến 8.
      • Không có mối quan hệ đơn điệu rõ ràng: Không thấy có mối quan hệ tuyến tính hay phi tuyến tính mạnh và đơn điệu giữa fixed_acidity và quality (ví dụ: fixed_acidity càng cao thì quality càng cao/thấp). Các mức chất lượng cao và thấp đều có xu hướng tập trung ở mức độ axit cố định trung bình.
In [49]:
def quality(variables):
    plt.figure(figsize=(16, 5))
    sns.histplot(data=wine_data, x=variables, hue="quality", kde=True,bins=20)
    if quality == "density": plt.title(f"\n{variables} of red wine\n\n")
    else: plt.title(f"\n{variables} contents in red wine\n\n")
    plt.figtext(0.75, 0.3, f'{wine_data[variables].describe()}')
    sns.despine()
In [48]:
quality("fixed_acidity")
plt.show
Out[48]:
<function matplotlib.pyplot.show(close=None, block=None)>
No description has been provided for this image
  • Nhận xét:

    • Phân bố chung của Độ Axit Cố định (fixed_acidity)

      • Thống kê Mô tả (fixed_acidity)

        • Số lượng mẫu (count): 1599 mẫu.
        • Giá trị trung bình (mean): Khoảng 8.32.
        • Độ lệch chuẩn (std): Khoảng 1.74.
        • Phân vị (Quartiles): 50% dữ liệu nằm trong khoảng 7.10 (25%) đến 9.20 (75%).
        • Khoảng giá trị: Từ 4.60 (min) đến 15.90 (max).
      • Hình dạng Phân bố

        • Phân bố tổng thể (fixed_acidity) có dạng lệch phải nhẹ (do mean≈8.32 lớn hơn median=7.90) và tập trung mạnh mẽ trong khoảng 6.5 đến 9.5.
    • Phân bố theo Chất lượng Rượu (quality)

      • Sự Tập trung Dữ liệu
        • Chất lượng Trung bình (quality=5,6): Hai mức chất lượng này chiếm phần lớn số lượng mẫu (được thể hiện qua chiều cao của các histogram và KDE). Phân bố của chúng gần như là phân bố chung, với đỉnh tập trung mạnh mẽ trong khoảng 7.0 đến 8.5.
        • Chất lượng Cao và Thấp: Các mức chất lượng cực đoan (quality=3,4,7,8) có số lượng mẫu ít hơn đáng kể (thanh histogram thấp hơn) so với quality=5 và quality=6.
    • Mối quan hệ fixed_acidity và quality

      • Chồng lấn (Overlap): Đây là nhận xét quan trọng nhất. Biểu đồ cho thấy sự chồng lấn rất lớn giữa các mức chất lượng. Tại hầu hết các giá trị fixed_acidity phổ biến (đặc biệt là từ 6.0 đến 11.0), ta có thể tìm thấy mẫu rượu thuộc nhiều mức chất lượng khác nhau (từ 4 đến 7 hoặc 8).
      • Không có Xu hướng Rõ ràng: Không thấy có mối quan hệ đơn điệu (tăng hoặc giảm đều đặn) rõ ràng giữa fixed_acidity và quality. Cả rượu chất lượng cao (quality=7,8) và chất lượng thấp (quality=4) đều có phân bố tập trung mạnh nhất ở các mức fixed_acidity trung bình (khoảng 7.0 đến 9.0).

Kết luận Sơ bộ:
- Đặc trưng Yếu: Biến fixed_acidity không phải là một đặc trưng phân loại chất lượng rượu mạnh khi xét độc lập, vì nó không đủ để tách biệt các nhóm chất lượng do hiện tượng chồng lấn dữ liệu rộng.
- Vai trò Tiềm năng: Để dự đoán chất lượng rượu hiệu quả, fixed_acidity cần được kết hợp với các biến hóa học khác (như pH, citric_acid, alcohol,...) để xây dựng một mô hình dự đoán đa biến.

In [45]:
#bar chart of average quantity ordered per country
dataForPlot = wine_data.groupby('quality').mean().residual_sugar
fig, ax = plt.subplots()
ax.barh(dataForPlot.index, dataForPlot, color=['C5', 'C1'])
ax.set_xticklabels(dataForPlot.index, rotation=90)
ax.set_xlabel('Avg. of Residual Sugar')
ax.set_ylabel('Quality')
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Phân bố Giá trị

      • Giá trị Trung bình của Đường dư nằm trong khoảng tương đối hẹp, chủ yếu từ khoảng 7.9 đến 8.5 cho tất cả các mức chất lượng.
      • Giá trị thấp nhất thuộc về Quality=8 (khoảng 8.1).
      • Giá trị cao nhất thuộc về Quality=4 (khoảng 8.4) và Quality=7 (khoảng 8.5).
    • Xu hướng Chất lượng

      • Không có mối quan hệ rõ ràng: Biểu đồ cho thấy không có mối quan hệ tuyến tính (Linear Relationship) hay xu hướng tăng/giảm rõ ràng giữa Quality và Avg. of Residual Sugar.
        • Rượu chất lượng thấp (Quality=3 và 4) và rượu chất lượng cao (Quality=7) đều có Avg. of Residual Sugar tương đối cao (khoảng 8.3 đến 8.5).
        • Rượu chất lượng trung bình (Quality=5,6) có giá trị Avg. of Residual Sugar nằm ở mức thấp hơn một chút (khoảng 8.1 đến 8.2).
      • Sự khác biệt không đáng kể: Mặc dù có sự khác biệt nhỏ về chiều dài thanh, sự khác biệt này (chỉ khoảng 0.4 đơn vị trên trục X) là rất nhỏ và khó có thể coi Residual Sugar là yếu tố phân biệt mạnh cho chất lượng rượu khi xét độc lập.

Kết luận Sơ bộ
- Biến Lượng đường dư (Residual Sugar) dường như không phải là yếu tố quyết định chính đến chất lượng rượu. Các mức chất lượng khác nhau có lượng đường dư trung bình gần như giống nhau.
- Điều này gợi ý rằng Residual Sugar có thể không đóng góp nhiều vào việc phân loại chất lượng rượu trong mô hình dự đoán, hoặc ảnh hưởng của nó bị chi phối bởi các yếu tố hóa học khác (như alcohol, pH, volatile_acidity).

In [ ]:
fig, ax = plt.subplots()
ax.hist(wine_data.density)
ax.set_axisbelow(True)  # Show the grid lines behind the histogram
ax.grid(which='major', color='grey', linestyle='--')
ax.set_xlabel('density')
ax.set_ylabel('count')
plt.show()
No description has been provided for this image
  • Nhận xét:
    • Dạng Phân bố

      • Hình dạng: Phân bố của density có dạng gần đối xứng và trông gần giống phân bố Chuẩn (Normal Distribution).
      • Đỉnh (Mode): Phân bố đạt đỉnh cao nhất (tần số lớn nhất, count gần 500) tại khoảng giá trị density từ 0.996 đến 0.998 (cụ thể là thanh histogram cao nhất).
    • Sự Tập trung và Khoảng biến thiên

      • Sự Tập trung: Phần lớn các mẫu dữ liệu (hơn 75%) tập trung rất mạnh mẽ trong khoảng density từ 0.994 đến 1.000.
      • Khoảng biến thiên: Giá trị density trải rộng từ khoảng 0.990 đến 1.004.
      • Giá trị Trung bình: Giá trị trung bình của density nằm đâu đó trong khoảng 0.996 đến 0.998 do tính đối xứng của phân bố.

Kết luận Sơ bộ
- Biến density có sự phân bố rất tập trung xung quanh một giá trị trung bình hẹp.
- Điều này gợi ý rằng, trong tập dữ liệu này (thường là dữ liệu về rượu vang), density là một đặc trưng khá ổn định và không có nhiều sự biến động lớn giữa các mẫu rượu.

In [ ]:
# Add the correlation coefficient to the scatterplots above the diagonal
from pandas.plotting import scatter_matrix, parallel_coordinates
df = wine_data[['volatile_acidity', 'sulphates', 'alcohol']]
axes = scatter_matrix(df, alpha=0.5, figsize=(6, 6), diagonal='kde') #kde is for density plots, you can use "hist" for histogram
corr = df.corr().values
for i, j in zip(*plt.np.triu_indices_from(axes, k=1)):
    axes[i, j].annotate("%.3f" %corr[i,j], (0.8, 0.8), xycoords='axes fraction', ha='center', va='center')

plt.show()
No description has been provided for this image
  • Nhận xét:
    • Phân bố Từng Biến (Đường chéo)

      • Phần đường chéo của ma trận hiển thị Biểu đồ ước lượng mật độ nhân (KDE - Kernel Density Estimate) cho từng biến:
        • volatile_acidity (Độ axit dễ bay hơi): Phân bố lệch phải mạnh. Đa số các mẫu có độ axit dễ bay hơi thấp, với đỉnh mật độ nằm dưới 0.5.
        • sulphates: Phân bố cũng lệch phải, tập trung cao tại mức sulphates khoảng 0.6 đến 0.8.
        • alcohol (Nồng độ cồn): Phân bố có dạng gần đối xứng hơn, có xu hướng béo ở đuôi phải hoặc có hai đỉnh (bimodal), tập trung chủ yếu trong khoảng 9.5 đến 12.5.
    • Mối quan hệ giữa các Biến (Biểu đồ Tán xạ)

      • Các biểu đồ ngoài đường chéo thể hiện mối quan hệ giữa hai biến, kèm theo hệ số tương quan Pearson (r) được hiển thị ở góc trên bên phải của biểu đồ tán xạ tương ứng (phần tam giác trên):

      • A. volatile_acidity vs sulphates

        • Hệ số tương quan (r=−0.261): Cho thấy mối quan hệ tương quan nghịch yếu (hoặc rất yếu).
        • Biểu đồ tán xạ: Các điểm dữ liệu phân tán rộng. Tuy nhiên, có một xu hướng mờ nhạt: khi volatile_acidity tăng, sulphates có xu hướng giảm nhẹ.
      • B. volatile_acidity vs alcohol

        • Hệ số tương quan (r=−0.202): Cho thấy mối quan hệ tương quan nghịch rất yếu.
        • Biểu đồ tán xạ: Các điểm dữ liệu rất phân tán. Không có mối quan hệ tuyến tính rõ ràng. Tuy nhiên, dữ liệu có vẻ trải rộng hơn ở mức alcohol cao hơn, và alcohol cao nhất thường đi kèm với volatile_acidity thấp.
      • C. sulphates vs alcohol

        • Hệ số tương quan (r=0.094): Cho thấy mối quan hệ tương quan thuận cực kỳ yếu (gần như không có tương quan tuyến tính).
        • Biểu đồ tán xạ: Các điểm dữ liệu phân tán hoàn toàn ngẫu nhiên và không tạo thành bất kỳ hình dạng hay xu hướng nào.

Kết luận Tổng thể
- Trong ba cặp biến được phân tích, không có cặp biến nào có mối quan hệ tuyến tính mạnh mẽ. Tất cả các hệ số tương quan đều rất gần 0 (từ −0.261 đến 0.094).
- Cặp biến có mối quan hệ tuyến tính rõ ràng nhất (dù vẫn yếu) là volatile_acidity và sulphates (r≈−0.261).
- Cặp sulphates và alcohol hầu như độc lập với nhau về mặt tuyến tính (r≈0.094).

In [ ]:
fig, axes = plt.subplots(nrows=1, ncols=3)
wine_data.boxplot(column='alcohol', by='quality', ax=axes[0])
wine_data.boxplot(column='volatile_acidity', by='quality', ax=axes[1])
wine_data.boxplot(column='sulphates', by='quality', ax=axes[2])
for ax in axes:
    ax.set_xlabel('quality')
plt.suptitle('')  # Suppress the overall title
plt.tight_layout()  # Increase the separation between the plots

plt.show()
No description has been provided for this image
  • Nhận xét:
    • Nồng độ Cồn (alcohol)

      • Xu hướng Rõ rệt: Có một mối quan hệ thuận (tương quan dương) rõ ràng giữa quality và alcohol.
        • Khi quality tăng từ 3 lên 8, giá trị trung vị (đường kẻ ngang bên trong hộp) và toàn bộ hộp (IQR) của alcohol có xu hướng dịch chuyển lên cao hơn.
        • Ví dụ: Rượu quality=3 và 4 có trung vị thấp (khoảng 9.8 và 10.0), trong khi quality=8 có trung vị cao nhất (khoảng 12.5).
      • Phân biệt Chất lượng: alcohol là một đặc trưng mạnh để phân biệt giữa các mức chất lượng, đặc biệt giữa nhóm chất lượng thấp/trung bình (3, 4, 5) và nhóm chất lượng cao (7, 8).
      • Ngoại lệ (Outliers): Có nhiều giá trị ngoại lệ ở hầu hết các mức chất lượng, đặc biệt là ở quality=5.
    • Độ Axit Dễ Bay hơi (volatile_acidity)

      • Xu hướng Rõ rệt: Có một mối quan hệ nghịch (tương quan âm) rõ ràng giữa quality và volatile_acidity.
        • Khi quality tăng từ 3 lên 8, giá trị trung vị và hộp (IQR) của volatile_acidity có xu hướng dịch chuyển xuống thấp hơn.
        • Ví dụ: Rượu quality=3 có trung vị cao nhất (khoảng 0.85), trong khi quality=8 có trung vị thấp nhất (khoảng 0.37).
      • Phân biệt Chất lượng: volatile_acidity là một đặc trưng mạnh để phân biệt chất lượng. Độ axit dễ bay hơi thấp thường gắn liền với chất lượng cao hơn.
      • Ngoại lệ (Outliers): Có nhiều giá trị ngoại lệ (cao) ở các mức chất lượng trung bình (4, 5, 6).
    • Sulphates (sulphates)

      • Xu hướng Yếu: Mối quan hệ giữa quality và sulphates không rõ ràng như hai biến trên, nhưng có xu hướng thuận nhẹ:
        • Giá trị trung vị và hộp cho quality=7 và quality=8 có vẻ cao hơn một chút so với các mức chất lượng thấp hơn (3, 4).
        • Trung vị của quality=3 và 4 thấp (khoảng 0.53), còn quality=7 và 8 cao hơn (khoảng 0.75).
      • Đặc điểm Nổi bật: Sự phân bố của sulphates bị chồng lấn rất nhiều giữa các mức chất lượng. Sự khác biệt giữa các hộp là không đáng kể.
      • Ngoại lệ (Outliers): Biến này có rất nhiều giá trị ngoại lệ cao ở tất cả các mức chất lượng, đặc biệt là quality=5.

    Kết luận Tổng thể
    - Các đặc trưng Quan trọng: alcohol (tương quan thuận) và volatile_acidity (tương quan nghịch) là hai đặc trưng hóa học quan trọng nhất để phân biệt chất lượng rượu.
    - Đặc trưng Yếu: sulphates có mối quan hệ yếu hơn và phân bố bị chồng lấn nhiều hơn, nhưng vẫn có vai trò trong việc cải thiện chất lượng ở các mức cao hơn.